﻿// -------------------------------------------------------------------------
//    @FileName         :    NFTransRoleOnline.cpp
//    @Author           :    gaoyi
//    @Date             :    2025-03-27
//    @Email			:    445267987@qq.com
//    @Module           :    NFTransRoleOnline
//
// -------------------------------------------------------------------------

#include "NFTransRoleOnline.h"

#include <NFSnsOnlineRoleService.h>
#include <NFSnsRoleDetail.h>
#include <NFSnsRoleDetailService.h>
#include <proto_svr_common.nanopb.h>
#include <NFLogicCommon/NFBaseDefine.h>
#include <NFServerComm/NFServerCommon/NFIServerMessageModule.h>
#include <NFSnsServer/NFSnsCommon/NFSnsRoleSimple.h>
#include <NFSnsServer/NFSnsCommon/NFSnsRoleSimpleService.h>

#include "NFTransInsertRoleDetail.h"
#include "NFTransLoadRoleDetail.h"
#include "ServerCommon.nanopb.h"
#include "NFServerComm/NFServerCommon/NFCacheDataMgr.h"
#include "NFSnsServer/NFSnsCommon/NFTransInsertRoleSimple.h"

NFTransRoleOnline::NFTransRoleOnline()
{
    if (NFShmMgr::Instance()->GetCreateMode() == EN_OBJ_MODE_INIT)
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFTransRoleOnline::~NFTransRoleOnline()
{
}

int NFTransRoleOnline::CreateInit()
{
    m_cmd = 0;
    m_logicSvrId = 0;
    m_lastLoginTime = 0;
    m_lastLogoutTime = 0;
    m_iServerType = NF_ST_SNS_SERVER;
    return 0;
}

int NFTransRoleOnline::ResumeInit()
{
    return 0;
}

int NFTransRoleOnline::RoleLogin(const proto_ff::Proto_GSLoginReq* pGsReq)
{
    CHECK_NULL(0, pGsReq);
    m_ullRoleId = pGsReq->role_id();
    m_cmd = E_GS_LOGIN_REQ;
    m_logicSvrId = pGsReq->gamesvr_id();
    m_simpleInfo.FromPb(pGsReq->role_info());
    m_lastLoginTime = pGsReq->last_login_time();
    m_lastLogoutTime = pGsReq->last_logout_time();

    QueryRole(REASON_CACHE_DATA_GET_OR_CREATE);
    return 0;
}

int NFTransRoleOnline::GetCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode, google::protobuf::Message* pMessage)
{
    if (iTableId == E_TABLE_SNS_ROLE_SIMPLE)
    {
        if (errCode != 0)
        {
            if (errCode == NFrame::ERR_CODE_STORESVR_ERRCODE_SELECT_EMPTY)
            {
                int iRetCode = InsertRoleSimpleReq(iReason);
                CHECK_ERR(m_ullRoleId, iRetCode, "InsertRoleSimpleReq fail");
                return 0;
            }
            else
            {
                LOG_ERR(m_ullRoleId, errCode, "get sns role simple info roleId:{} errCode:{}", m_ullRoleId, errCode);
                SetFinished(errCode);
                return 0;
            }
        }

        auto pTbSnsRoleSimple = dynamic_cast<proto_ff::tbSnsRoleSimpleInfo*>(pMessage);
        CHECK_NULL_WF(m_ullRoleId, pTbSnsRoleSimple, "dynamic_cast<tbSnsRoleSimpleInfo> failed, roleId:{}", m_ullRoleId);

        auto pSnsRoleSimple = NFCacheDataMgr::Instance()->AddCacheData<NFSnsRoleSimple>(pTbSnsRoleSimple);
        CHECK_NULL_WF(m_ullRoleId, pSnsRoleSimple, "AddCacheData failed, roleId:{}", m_ullRoleId);

        auto pRoleDetail = NFSnsRoleDetailService::GetRoleDetail(m_ullRoleId);
        if (pRoleDetail == nullptr)
        {
            int iRetCode = GetCacheDataSingleReq<NFTransLoadRoleDetail>(m_ullRoleId, iReason, E_TABLE_SNS_ROLE_DETAIL);
            CHECK_ERR(m_ullRoleId, iRetCode, "GetRoleDetailInfoBatchReq fail");
            return 0;
        }
        else
        {
            SetFinished(0);
        }
    }
    else if (iTableId == E_TABLE_SNS_ROLE_DETAIL)
    {
        if (errCode != 0)
        {
            if (errCode == NFrame::ERR_CODE_STORESVR_ERRCODE_SELECT_EMPTY)
            {
                int iRetCode = InsertRoleDetailReq(iReason);
                CHECK_ERR(m_ullRoleId, iRetCode, "InsertRoleDetailReq fail");
                return 0;
            }
            else
            {
                LOG_ERR(m_ullRoleId, errCode, "get sns role detail info failed roleId:{}", m_ullRoleId);
                SetFinished(errCode);
                return 0;
            }
        }

        auto pTbSnsRoleDetail = dynamic_cast<proto_ff::tbSnsRoleDetail*>(pMessage);
        CHECK_NULL_WF(m_ullRoleId, pTbSnsRoleDetail, "dynamic_cast<tbSnsRoleSimpleInfo> failed, roleId:{}", m_ullRoleId);

        auto pRoleDetail = NFSnsRoleDetailService::AddRoleDetail(m_ullRoleId, pTbSnsRoleDetail);
        CHECK_NULL(m_ullRoleId, pRoleDetail);

        LOG_INFO(m_ullRoleId, "get sns role detail info success, roleId:{}", m_ullRoleId);
        SetFinished(0);
        return 0;
    }

    SetFinished(-1);
    return 0;
}

int NFTransRoleOnline::InsertCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode, google::protobuf::Message* pMessage)
{
    if (iTableId == E_TABLE_SNS_ROLE_SIMPLE)
    {
        if (errCode != 0)
        {
            LOG_ERR(m_ullRoleId, errCode, "Insert Role Detail to Db Failed, errCode:{}", errCode);
            SetFinished(errCode);
            return 0;
        }

        auto pTbSnsRoleSimple = dynamic_cast<proto_ff::tbSnsRoleSimpleInfo*>(pMessage);
        CHECK_NULL_WF(m_ullRoleId, pTbSnsRoleSimple, "dynamic_cast<tbSnsRoleSimpleInfo> failed, roleId:{}", m_ullRoleId);

        auto pSnsRoleSimple = NFCacheDataMgr::Instance()->AddCacheData<NFSnsRoleSimple>(pTbSnsRoleSimple);
        CHECK_NULL_WF(m_ullRoleId, pSnsRoleSimple, "AddCacheData failed, roleId:{}", m_ullRoleId);

        auto pRoleDetail = NFSnsRoleDetailService::GetRoleDetail(m_ullRoleId);
        if (pRoleDetail == nullptr)
        {
            int iRetCode = GetCacheDataSingleReq<NFTransLoadRoleDetail>(m_ullRoleId, iReason, E_TABLE_SNS_ROLE_DETAIL);
            CHECK_ERR(m_ullRoleId, iRetCode, "GetRoleDetailInfoBatchReq fail");
        }
        else
        {
            SetFinished(0);
        }
        return 0;
    }
    else if (iTableId == E_TABLE_SNS_ROLE_DETAIL)
    {
        if (errCode != 0)
        {
            LOG_ERR(m_ullRoleId, errCode, "Insert Role Detail to Db Failed, errCode:{}", errCode);
            SetFinished(errCode);
            return 0;
        }

        auto pTbSnsRoleDetail = dynamic_cast<proto_ff::tbSnsRoleDetail*>(pMessage);
        CHECK_NULL_WF(m_ullRoleId, pTbSnsRoleDetail, "dynamic_cast<tbSnsRoleSimpleInfo> failed, roleId:{}", m_ullRoleId);

        auto pRoleDetail = NFSnsRoleDetailService::AddRoleDetail(m_ullRoleId, pTbSnsRoleDetail);
        CHECK_NULL(m_ullRoleId, pRoleDetail);
    }
    else
    {
        LOG_ERR(m_ullRoleId, errCode, "InsertCacheDataBatchRes not handle tableId:{}", iTableId);
        SetFinished(-1);
        return 0;
    }

    SetFinished(0);
    return 0;
}

int NFTransRoleOnline::InsertRoleDetailReq(int iReason)
{
    int iRetCode = InsertCacheDataReq<NFTransInsertRoleDetail>(m_ullRoleId, iReason, E_TABLE_SNS_ROLE_DETAIL);
    CHECK_ERR(m_ullRoleId, iRetCode, "InsertCacheDataReq<NFTransInsertRoleDetail> fail");
    return 0;
}

int NFTransRoleOnline::OnTransFinished(int iRunLogicRetCode)
{
    if (m_cmd == proto_ff::E_GS_LOGIN_REQ)
    {
        OnRoleLogin(iRunLogicRetCode);
    }
    else
    {
        OnRoleRestore(iRunLogicRetCode);
    }

    return 0;
}

int NFTransRoleOnline::InsertRoleSimpleReq(int iReason)
{
    proto_ff::tbSnsRoleSimpleInfo roleSimpleInfo;
    roleSimpleInfo.set_role_id(m_ullRoleId);
    NFSnsRoleSimple::MakeInitData(*roleSimpleInfo.mutable_role_info(), m_ullRoleId);
    int iRetCode = InsertCacheDataReq<NFTransInsertRoleSimple>(m_ullRoleId, iReason, roleSimpleInfo, E_TABLE_SNS_ROLE_SIMPLE);
    CHECK_ERR(m_ullRoleId, iRetCode, "InsertCacheDataReq<NFTransInsertRoleSimple> fail");
    return 0;
}

int NFTransRoleOnline::OnRoleLogin(int errCode)
{
    proto_ff::Proto_SGLoginRsp rsp;

    rsp.set_role_id(m_ullRoleId);
    rsp.set_gamesvr_id(m_logicSvrId);

    if (errCode != 0)
    {
        LOG_ERR(m_ullRoleId, errCode, "Role Sns Login Failed, errCode:{}", errCode);
        rsp.set_result(proto_ff::ERR_CODE_SYSTEM_DATABASE_ERROR);
        FindModule<NFIServerMessageModule>()->SendMsgToLogicServer(NF_ST_SNS_SERVER, m_logicSvrId, proto_ff::E_SG_LOGIN_RSP, rsp);
        return 0;
    }

    auto pRoleSimple = NFSnsRoleSimpleService::GetRoleSimple(m_ullRoleId);
    CHECK_NULL_WF(m_ullRoleId, pRoleSimple, "GetRoleSimple Failed");
    pRoleSimple->InitData(m_simpleInfo);
    pRoleSimple->MarkDirty();

    auto pRoleDetail = NFSnsRoleDetailService::GetRoleDetail(m_ullRoleId);
    CHECK_NULL_WF(m_ullRoleId, pRoleDetail, "GetRoleDetail Failed");

    //正常流程-- 先判定是否能登录->是否已经在线->允许登录
    auto pOnlineRole = NFSnsOnlineRoleService::GetOnlineRole(m_ullRoleId);
    if (pOnlineRole == nullptr)
    {
        pOnlineRole = NFSnsOnlineRoleService::AddOnlineRole(m_ullRoleId);
        if (pOnlineRole == nullptr)
        {
            rsp.set_result(proto_ff::ERR_CODE_LOGIN_REACH_MAX_NUM);
            return 0;
        }

        pOnlineRole->Init(m_ullRoleId, m_logicSvrId, m_lastLoginTime, m_lastLogoutTime);
    }

    pOnlineRole->SetLogicSvrId(m_logicSvrId);

    rsp.set_result(0);
    pOnlineRole->SendMsgToLogicServer(proto_ff::E_SG_LOGIN_RSP, rsp);

    NFSnsRoleDetailService::LoginRole(pRoleDetail, false);
    LOG_INFO(m_ullRoleId, "Role Sns Login Success, roleId:{}", m_ullRoleId);
    return 0;
}

int NFTransRoleOnline::OnRoleRestore(int errCode)
{
    return 0;
}
